From: cl349@freefall.cl.cam.ac.uk Date: Tue, 7 Sep 2004 16:05:53 +0000 (+0000) Subject: bitkeeper revision 1.1159.1.131 (413ddc610qK3tZi2_2-e23mt5avoNA) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~17400^2~620 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks:///%22http:/www.example.com/cgi/%22https:/%22bookmarks:/?a=commitdiff_plain;h=f11bc5a8fcd2fc973db017fceed97a963598381b;p=xen.git bitkeeper revision 1.1159.1.131 (413ddc610qK3tZi2_2-e23mt5avoNA) Load (Net)BSD symbol table from ELF image if requested. --- diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S index 45af67272f..6a1a3e7bd8 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S @@ -180,7 +180,12 @@ * Xen guest identifier and loader selection */ .section __xen_guest - .asciz "GUEST_OS=netbsd,GUEST_VER=2.0,XEN_VER=2.0,LOADER=generic" + .ascii "GUEST_OS=netbsd,GUEST_VER=2.0,XEN_VER=2.0" + .ascii ",LOADER=generic" +#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE) + .ascii ",BSD_SYMTAB" +#endif + .byte 0 /* @@ -189,7 +194,7 @@ .data .globl _C_LABEL(cpu) - .globl _C_LABEL(esym),_C_LABEL(boothowto) + .globl _C_LABEL(boothowto) .globl _C_LABEL(bootinfo),_C_LABEL(atdevbase) #ifdef COMPAT_OLDBOOT .globl _C_LABEL(bootdev) @@ -228,7 +233,6 @@ _C_LABEL(lapic_tpr): _C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, # or Pentium, or.. -_C_LABEL(esym): .long 0 # ptr to end of syms _C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual _C_LABEL(proc0paddr): .long 0 _C_LABEL(PTDpaddr): .long 0 # paddr of PTD, for libkvm @@ -254,11 +258,6 @@ tmpstk: #define _RELOC(x) ((x)) #define RELOC(x) _RELOC(_C_LABEL(x)) -/* XXX assym.h */ -#define MOD_START 48 -#define MOD_LEN 56 -/* XXX assym.h */ - .text .globl _C_LABEL(kernel_text) .set _C_LABEL(kernel_text),KERNTEXTOFF @@ -271,13 +270,6 @@ start: movl %esi,%ebx # save start_info pointer -#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE) - /* Save the symbol locations. */ - movl MOD_START(%ebx),%esi - addl MOD_LEN(%ebx),%esi - movl %esi,RELOC(esym) -#endif - /* Clear BSS first so that there are no surprises... */ xorl %eax,%eax movl $RELOC(__bss_start),%edi diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c index 61d2898096..5ec2d45271 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c @@ -2061,7 +2061,6 @@ init386(paddr_t first_avail) #if NKSYMS || defined(DDB) || defined(LKM) { extern int end; - extern int *esym; struct btinfo_symtab *symtab; #ifdef DDB @@ -2077,7 +2076,10 @@ init386(paddr_t first_avail) (int *)symtab->esym); } else - ksyms_init(*(int *)&end, ((int *)&end) + 1, esym); + ksyms_init(*(int *)&end, ((int *)&end) + 1, + xen_start_info.mod_start ? + (void *)xen_start_info.mod_start : + (void *)xen_start_info.mfn_list); } #endif #ifdef DDB diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index bb44e27bac..04e2ac7e4e 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -17,11 +17,16 @@ struct domain_setup_info { unsigned long v_start; + unsigned long v_end; unsigned long v_kernstart; unsigned long v_kernend; unsigned long v_kernentry; unsigned int use_writable_pagetables; + unsigned int load_bsd_symtab; + + unsigned long symtab_addr; + unsigned long symtab_len; }; static int parseelfimage(char *elfbase, @@ -29,6 +34,8 @@ static int parseelfimage(char *elfbase, struct domain_setup_info *dsi); static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray, unsigned long vstart); +static int loadelfsymtab(char *elfbase, void *pmh, unsigned long *parray, + struct domain_setup_info *dsi); static long get_tot_pages(int xc_handle, u32 domid) { @@ -125,6 +132,9 @@ static int setup_guestos(int xc_handle, xc_domain_setvmassist(xc_handle, dom, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); + if (dsi.load_bsd_symtab) + loadelfsymtab(image, NULL, NULL, &dsi); + if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 ) { PERROR("Guest OS must load to a page boundary.\n"); @@ -138,13 +148,13 @@ static int setup_guestos(int xc_handle, * read-only). We have a pair of simultaneous equations in two unknowns, * which we solve by exhaustive search. */ + vinitrd_start = round_pgup(dsi.v_end); + vinitrd_end = vinitrd_start + initrd_len; + vphysmap_start = round_pgup(vinitrd_end); + vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); + vpt_start = round_pgup(vphysmap_end); for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { - vinitrd_start = round_pgup(dsi.v_kernend); - vinitrd_end = vinitrd_start + initrd_len; - vphysmap_start = round_pgup(vinitrd_end); - vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); - vpt_start = round_pgup(vphysmap_end); vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); vstartinfo_start = vpt_end; vstartinfo_end = vstartinfo_start + PAGE_SIZE; @@ -200,6 +210,9 @@ static int setup_guestos(int xc_handle, loadelfimage(image, pm_handle, page_array, dsi.v_start); + if (dsi.load_bsd_symtab) + loadelfsymtab(image, pm_handle, page_array, &dsi); + /* Load the initial ramdisk image. */ if ( initrd_len != 0 ) { @@ -656,10 +669,15 @@ static int parseelfimage(char *elfbase, if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL ) dsi->use_writable_pagetables = 1; + if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) + dsi->load_bsd_symtab = 1; + dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; dsi->v_kernentry = ehdr->e_entry; + dsi->v_end = dsi->v_kernend; + return 0; } @@ -706,3 +724,114 @@ static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray, return 0; } +static void map_memcpy(unsigned long dst, char *src, unsigned long size, + void *pmh, unsigned long *parray, unsigned long vstart) +{ + char *va; + unsigned long chunksz, done, pa; + + for ( done = 0; done < size; done += chunksz ) + { + pa = dst + done - vstart; + va = map_pfn_writeable(pmh, parray[pa>>PAGE_SHIFT]); + chunksz = size - done; + if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) + chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); + memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz); + unmap_pfn(pmh, va); + } +} + +#define ELFROUND (ELFSIZE / 8) + +static int loadelfsymtab(char *elfbase, void *pmh, unsigned long *parray, + struct domain_setup_info *dsi) +{ + Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr; + Elf_Shdr *shdr; + unsigned long maxva, symva; + char *p; + int h, i; + + p = malloc(sizeof(int) + sizeof(Elf_Ehdr) + + ehdr->e_shnum * sizeof(Elf_Shdr)); + if (p == NULL) + return 0; + + maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); + symva = maxva; + maxva += sizeof(int); + dsi->symtab_addr = maxva; + dsi->symtab_len = 0; + maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); + + shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); + memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr)); + + for ( h = 0; h < ehdr->e_shnum; h++ ) + { + if ( shdr[h].sh_type == SHT_STRTAB ) + { + /* Look for a strtab @i linked to symtab @h. */ + for ( i = 0; i < ehdr->e_shnum; i++ ) + if ( (shdr[i].sh_type == SHT_SYMTAB) && + (shdr[i].sh_link == h) ) + break; + /* Skip symtab @h if we found no corresponding strtab @i. */ + if ( i == ehdr->e_shnum ) + { + shdr[h].sh_offset = 0; + continue; + } + } + + if ( (shdr[h].sh_type == SHT_STRTAB) || + (shdr[h].sh_type == SHT_SYMTAB) ) + { + if ( pmh != NULL ) + map_memcpy(maxva, elfbase + shdr[h].sh_offset, shdr[h].sh_size, + pmh, parray, dsi->v_start); + + /* Mangled to be based on ELF header location. */ + shdr[h].sh_offset = maxva - dsi->symtab_addr; + + dsi->symtab_len += shdr[h].sh_size; + maxva += shdr[h].sh_size; + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); + } + + shdr[h].sh_name = 0; /* Name is NULL. */ + } + + if ( dsi->symtab_len == 0 ) + { + dsi->symtab_addr = 0; + goto out; + } + + if ( pmh != NULL ) { + *(int *)p = maxva - dsi->symtab_addr; + sym_ehdr = (Elf_Ehdr *)(p + sizeof(int)); + memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr)); + sym_ehdr->e_phoff = 0; + sym_ehdr->e_shoff = sizeof(Elf_Ehdr); + sym_ehdr->e_phentsize = 0; + sym_ehdr->e_phnum = 0; + sym_ehdr->e_shstrndx = SHN_UNDEF; + + /* Copy total length, crafted ELF header and section header table */ + map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) + + ehdr->e_shnum * sizeof(Elf_Shdr), pmh, parray, + dsi->v_start); + } + + dsi->symtab_len = maxva - dsi->symtab_addr; + dsi->v_end = round_pgup(maxva); + + out: + if ( p != NULL ) + free(p); + + return 0; +}